from flask import Blueprint, request, current_app
from datetime import datetime
from app.utils.mysql_db import get_db_connection
from app.utils.logger import log_api_call


bp = Blueprint("restart_history", __name__)


@bp.get("")
@log_api_call("restart_history.list_history")
def list_history():
    """获取重启历史列表，支持分页、搜索、筛选"""
    current_app.logger.info("Listing restart history")
    
    # 获取查询参数
    restart_type = request.args.get("restart_type")
    job_name = request.args.get("job_name")
    host = request.args.get("host")
    service_type = request.args.get("service_type")
    action = request.args.get("action")
    status = request.args.get("status")
    triggered_by = request.args.get("triggered_by")
    start_time = request.args.get("start_time")
    end_time = request.args.get("end_time")
    page = request.args.get("page", 1, type=int)
    size = request.args.get("size", 20, type=int)
    
    # 获取排序参数（默认按 created_time DESC）
    sort_field = request.args.get("sort", "created_time")
    sort_order = request.args.get("order", "desc").upper()
    
    # 构建查询条件
    where = []
    params = []
    
    if restart_type:
        where.append("restart_type = %s")
        params.append(restart_type)
    
    if job_name:
        where.append("job_name LIKE %s")
        params.append(f"%{job_name}%")
    
    if host:
        where.append("host LIKE %s")
        params.append(f"%{host}%")
    
    if service_type:
        where.append("service_type = %s")
        params.append(service_type)
    
    if action:
        where.append("action = %s")
        params.append(action)
    
    if status:
        where.append("status = %s")
        params.append(status)
    
    if triggered_by:
        where.append("triggered_by LIKE %s")
        params.append(f"%{triggered_by}%")
    
    if start_time:
        where.append("created_time >= %s")
        params.append(start_time)
    
    if end_time:
        where.append("created_time <= %s")
        params.append(end_time)
    
    where_sql = (" WHERE " + " AND ".join(where)) if where else ""
    
    # 白名单验证排序字段
    valid_sort_fields = [
        "id", "restart_type", "action", "status", "created_time", 
        "completed_time", "duration_seconds", "job_name", "host", 
        "service_type", "triggered_by"
    ]
    if sort_field not in valid_sort_fields:
        sort_field = "created_time"
    if sort_order not in ["ASC", "DESC"]:
        sort_order = "DESC"
    
    order_by_clause = f"ORDER BY {sort_field} {sort_order}"
    
    conn = get_db_connection()
    try:
        with conn.cursor() as cur:
            # 获取总数（考虑筛选条件）
            count_sql = f"SELECT COUNT(*) as total FROM flink_cluster_restart_history {where_sql}"
            cur.execute(count_sql, params)
            total_result = cur.fetchone()
            total = total_result['total'] if total_result else 0
            
            # 查询全局总数（不考虑筛选条件，用于统计卡片）
            cur.execute("SELECT COUNT(*) as total FROM flink_cluster_restart_history")
            total_all_result = cur.fetchone()
            total_all = total_all_result['total'] if total_all_result else 0
            
            # 获取统计数据（成功、失败、进行中）
            stats_sql = "SELECT status, COUNT(*) as count FROM flink_cluster_restart_history GROUP BY status"
            cur.execute(stats_sql)
            stats_rows = cur.fetchall()
            stats = {
                'success': 0,
                'failed': 0,
                'attempting': 0
            }
            for row in stats_rows:
                status_val = row['status']
                count = row['count']
                if status_val == 'SUCCESS':
                    stats['success'] = count
                elif status_val == 'FAILED':
                    stats['failed'] = count
                elif status_val == 'ATTEMPTING':
                    stats['attempting'] = count
            
            # 获取分页数据
            offset = (page - 1) * size
            cur.execute(
                f"""
                SELECT 
                    id, restart_type, host, service_type,
                    job_id, job_name, jar_name, jar_path, entry_class, 
                    program_args, savepoint_path, use_savepoint, recovery_reason,
                    action, status, error_message, created_time, completed_time,
                    duration_seconds, original_failure_reason, triggered_by
                FROM flink_cluster_restart_history
                {where_sql}
                {order_by_clause}
                LIMIT %s OFFSET %s
                """,
                (*params, size, offset),
            )
            rows = cur.fetchall()
            
            # 格式化时间字段和计算耗时
            for row in rows:
                created_time_obj = row.get('created_time')
                completed_time_obj = row.get('completed_time')
                
                # 如果 duration_seconds 为 NULL，先尝试计算（使用原始 datetime 对象）
                if row.get('duration_seconds') is None and created_time_obj and completed_time_obj:
                    try:
                        if hasattr(created_time_obj, 'strftime') and hasattr(completed_time_obj, 'strftime'):
                            duration = int((completed_time_obj - created_time_obj).total_seconds())
                            row['duration_seconds'] = duration
                    except:
                        pass
                
                # 格式化时间字段为字符串
                if created_time_obj and hasattr(created_time_obj, 'strftime'):
                    row['created_time'] = created_time_obj.strftime('%Y-%m-%d %H:%M:%S')
                if completed_time_obj and hasattr(completed_time_obj, 'strftime'):
                    row['completed_time'] = completed_time_obj.strftime('%Y-%m-%d %H:%M:%S')
            
            return {
                "success": True,
                "message": "ok",
                "data": {
                    "rows": rows,
                    "total": total,
                    "total_all": total_all,
                    "stats": stats,
                    "page": page,
                    "size": size
                }
            }
    finally:
        conn.close()


@bp.get("/<int:history_id>")
@log_api_call("restart_history.get_history_detail")
def get_history_detail(history_id):
    """获取重启历史详情"""
    current_app.logger.info(f"Getting restart history detail | id: {history_id}")
    
    conn = get_db_connection()
    try:
        with conn.cursor() as cur:
            cur.execute("""
                SELECT 
                    id, restart_type, host, service_type,
                    job_id, job_name, jar_name, jar_path, entry_class, 
                    program_args, savepoint_path, use_savepoint, recovery_reason,
                    action, status, error_message, created_time, completed_time,
                    duration_seconds, original_failure_reason, triggered_by
                FROM flink_cluster_restart_history
                WHERE id = %s
            """, (history_id,))
            row = cur.fetchone()
            
            if not row:
                return {
                    "success": False,
                    "message": "重启历史记录不存在",
                    "data": None
                }, 404
            
            created_time_obj = row.get('created_time')
            completed_time_obj = row.get('completed_time')
            
            # 如果 duration_seconds 为 NULL，先尝试计算（使用原始 datetime 对象）
            if row.get('duration_seconds') is None and created_time_obj and completed_time_obj:
                try:
                    if hasattr(created_time_obj, 'strftime') and hasattr(completed_time_obj, 'strftime'):
                        duration = int((completed_time_obj - created_time_obj).total_seconds())
                        row['duration_seconds'] = duration
                except:
                    pass
            
            # 格式化时间字段为字符串
            if created_time_obj and hasattr(created_time_obj, 'strftime'):
                row['created_time'] = created_time_obj.strftime('%Y-%m-%d %H:%M:%S')
            if completed_time_obj and hasattr(completed_time_obj, 'strftime'):
                row['completed_time'] = completed_time_obj.strftime('%Y-%m-%d %H:%M:%S')
            
            return {
                "success": True,
                "message": "ok",
                "data": row
            }
    finally:
        conn.close()

